package dao

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"smart-health-platforms/config"
	"smart-health-platforms/pkg"
	"strconv"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.uber.org/zap"
)

// 时间范围结构体（补充定义，确保跨模块可用）

// 血糖健康报告结构体
type BloodSugarReport struct {
	UserID          uint64                     `json:"user_id"`          // 用户ID
	RecordCount     int                        `json:"record_count"`     // 记录总数
	TimeRange       TimeRange                  `json:"time_range"`       // 测量时间范围
	BloodSugar      BloodSugarStats            `json:"blood_sugar"`      // 血糖统计
	HealthAdvice    []string                   `json:"health_advice"`    // 健康建议
	DetailedRecords []BloodSugarDetailedRecord `json:"detailed_records"` // 详细记录
	CreatedAt       string                     `json:"created_at"`       // 报告生成时间
}

// 血糖详细记录（RecordID 明确为字符串类型）
type BloodSugarDetailedRecord struct {
	RecordID       string  `json:"record_id"`       // 记录ID（来自MongoDB的_id，字符串类型）
	DeviceID       uint64  `json:"device_id"`       // 设备ID
	CollectionTime string  `json:"collection_time"` // 采集时间
	BloodSugar     float32 `json:"blood_sugar"`     // 血糖值（mmol/L）
	Status         string  `json:"status"`          // 状态（正常/偏高/偏低）
	MealStatus     string  `json:"meal_status"`     // 餐前/餐后状态
}

// 血糖统计数据
type BloodSugarStats struct {
	Max   float32 `json:"max"`   // 最大血糖
	Min   float32 `json:"min"`   // 最小血糖
	Avg   float32 `json:"avg"`   // 平均血糖
	Unit  string  `json:"unit"`  // 单位（mmol/L）
	Trend string  `json:"trend"` // 趋势（上升/下降/平稳）
}

// 查询用户的血糖记录
func queryBloodSugarRecords(userID uint64, collectionName string) ([]bson.M, error) {
	collection := config.HealthDB.Collection(collectionName)
	filter := bson.M{"user_id": userID, "data_type": "glucose"}
	sort := bson.M{"collection_time": 1} // 按时间升序排序

	cursor, err := collection.Find(context.Background(), filter, options.Find().SetSort(sort))
	if err != nil {
		pkg.Warn("查询血糖数据失败", zap.Error(err))
		return nil, fmt.Errorf("查询失败: %w", err)
	}
	defer cursor.Close(context.Background())

	var records []bson.M
	if err := cursor.All(context.Background(), &records); err != nil {
		pkg.Warn("解析血糖记录失败", zap.Error(err))
		return nil, fmt.Errorf("解析失败: %w", err)
	}
	return records, nil
}

// 生成血糖健康建议
func generateBloodSugarHealthAdvice(stats BloodSugarStats) []string {
	var advice []string

	// 基础健康知识
	advice = append(advice, "正常血糖范围：空腹3.9-6.1 mmol/L，餐后2小时<7.8 mmol/L。")

	// 基于平均值的建议
	switch {
	case stats.Avg > 11.1:
		advice = append(advice, "⚠️ 您的平均血糖显著偏高（>11.1 mmol/L），可能存在糖尿病风险，建议立即就医。")
	case stats.Avg > 7.8:
		advice = append(advice, "🔴 您的平均血糖偏高（>7.8 mmol/L），建议控制饮食并增加运动。")
	case stats.Avg < 3.9:
		advice = append(advice, "🔵 您的平均血糖偏低（<3.9 mmol/L），请注意低血糖风险，适当加餐。")
	case stats.Avg < 4.4:
		advice = append(advice, "🟡 您的平均血糖略偏低，建议监测餐前血糖变化。")
	default:
		advice = append(advice, "✅ 您的平均血糖在正常范围内，继续保持良好生活习惯。")
	}

	// 基于趋势的建议
	switch stats.Trend {
	case "上升":
		advice = append(advice, "📈 血糖呈上升趋势，请注意饮食控制和适当运动。")
	case "下降":
		advice = append(advice, "📉 血糖呈下降趋势，若伴随规律用药和运动属正常改善。")
	case "平稳":
		advice = append(advice, "📊 血糖保持相对稳定，控制效果良好。")
	default:
		advice = append(advice, "ℹ️ 数据不足，无法判断血糖趋势。")
	}

	// 通用建议
	advice = append(advice, "建议：均衡饮食，少食多餐，定期监测血糖，保持适度运动。")
	return advice
}

// 分析血糖趋势
func analyzeBloodSugarTrend(records []BloodSugarDetailedRecord) string {
	if len(records) < 3 {
		return "数据不足，无法判断趋势"
	}

	mid := len(records) / 2
	earlyCount := min(3, mid)
	lateCount := min(3, len(records)-mid)

	var earlyAvg, lateAvg float32
	for i := 0; i < earlyCount; i++ {
		earlyAvg += records[i].BloodSugar
	}
	earlyAvg /= float32(earlyCount)

	for i := len(records) - lateCount; i < len(records); i++ {
		lateAvg += records[i].BloodSugar
	}
	lateAvg /= float32(lateCount)

	// 趋势判断阈值：0.5 mmol/L
	const threshold = 0.5
	if lateAvg-earlyAvg > threshold {
		return "上升"
	} else if earlyAvg-lateAvg > threshold {
		return "下降"
	}
	return "平稳"
}

// 判断餐前餐后状态（根据时间判断）
func getMealStatus(collectionTime time.Time) string {
	hour := collectionTime.Hour()
	switch {
	case hour >= 6 && hour < 10:
		return "早餐后"
	case hour >= 10 && hour < 14:
		return "午餐前"
	case hour >= 14 && hour < 18:
		return "午餐后"
	case hour >= 18 && hour < 22:
		return "晚餐后"
	default:
		return "空腹"
	}
}

// 判断血糖状态（结合餐前/餐后）
func getBloodSugarStatus(value float32, mealStatus string) string {
	switch mealStatus {
	case "空腹":
		if value < 3.9 {
			return "偏低"
		} else if value > 6.1 {
			return "偏高"
		}
	case "早餐后", "午餐后", "晚餐后":
		if value < 4.4 {
			return "偏低"
		} else if value > 7.8 {
			return "偏高"
		}
	}
	return "正常"
}

// 解析时间字段（兼容多种类型）
func gparseTimeField(value interface{}) (time.Time, error) {
	switch v := value.(type) {
	case time.Time:
		return v, nil
	case string:
		// 尝试解析为秒级时间戳
		tsInt, err := strconv.ParseInt(v, 10, 64)
		if err == nil {
			return time.Unix(tsInt, 0), nil
		}
		// 尝试解析为RFC3339格式
		ts, err := time.Parse(time.RFC3339, v)
		if err == nil {
			return ts, nil
		}
		return time.Time{}, fmt.Errorf("无法解析时间: %v", v)
	default:
		return time.Time{}, fmt.Errorf("不支持的时间类型: %T", v)
	}
}

// 解析设备ID（兼容多种数字类型）
func gparseDeviceID(value interface{}) (uint64, error) {
	switch v := value.(type) {
	case int64:
		return uint64(v), nil
	case int32:
		return uint64(v), nil
	case int:
		return uint64(v), nil
	case string:
		num, err := strconv.ParseUint(v, 10, 64)
		if err != nil {
			return 0, fmt.Errorf("设备ID解析失败: %v", err)
		}
		return num, nil
	default:
		return 0, fmt.Errorf("不支持的设备ID类型: %T", v)
	}
}

// 生成血糖健康报告
func GenerateBloodSugarReport(userID uint64, collectionName string) (*BloodSugarReport, error) {
	// 1. 查询血糖记录
	records, err := queryBloodSugarRecords(userID, collectionName)
	if err != nil {
		return nil, fmt.Errorf("获取记录失败: %w", err)
	}

	// 2. 处理记录数据
	detailedRecords := make([]BloodSugarDetailedRecord, 0, len(records))
	var totalBloodSugar float32
	var maxBloodSugar, minBloodSugar float32
	var earliestTime, latestTime time.Time
	var hasRecords bool // 标记是否有有效记录

	for _, record := range records {
		// 解析时间
		ts, err := gparseTimeField(record["collection_time"])
		if err != nil {
			log.Printf("跳过无效时间记录: %v, 错误: %v", record["_id"], err)
			continue
		}

		// 解析血糖值
		bsVal, ok := record["result"].(float64)
		if !ok {
			log.Printf("跳过无效血糖值记录: %v (字段类型错误)", record["_id"])
			continue
		}
		bloodSugar := float32(bsVal)

		// 解析记录ID（来自MongoDB的_id）
		recordID, err := parseRecordID(record["_id"])
		if err != nil {
			log.Printf("跳过无效记录ID: %v, 错误: %v", record["_id"], err)
			continue
		}

		// 解析设备ID
		deviceID, err := gparseDeviceID(record["device_id"])
		if err != nil {
			log.Printf("跳过无效设备ID记录 (record_id=%s): %v", recordID, err)
			continue
		}

		// 初始化统计值（第一条有效记录）
		if !hasRecords {
			maxBloodSugar, minBloodSugar = bloodSugar, bloodSugar
			earliestTime, latestTime = ts, ts
			hasRecords = true
		} else {
			// 更新统计值
			if bloodSugar > maxBloodSugar {
				maxBloodSugar = bloodSugar
			}
			if bloodSugar < minBloodSugar {
				minBloodSugar = bloodSugar
			}
			if ts.Before(earliestTime) {
				earliestTime = ts
			}
			if ts.After(latestTime) {
				latestTime = ts
			}
		}

		// 累加总和
		totalBloodSugar += bloodSugar

		// 判断状态
		mealStatus := getMealStatus(ts)
		status := getBloodSugarStatus(bloodSugar, mealStatus)

		// 添加详细记录
		detailedRecords = append(detailedRecords, BloodSugarDetailedRecord{
			RecordID:       recordID,
			DeviceID:       deviceID,
			CollectionTime: ts.Format("2006-01-02 15:04:05"),
			BloodSugar:     bloodSugar,
			Status:         status,
			MealStatus:     mealStatus,
		})
	}

	// 3. 处理空记录场景
	recordCount := len(detailedRecords)
	if recordCount == 0 {
		return &BloodSugarReport{
			UserID:      userID,
			RecordCount: 0,
			TimeRange: TimeRange{
				Earliest: "无记录",
				Latest:   "无记录",
			},
			BloodSugar: BloodSugarStats{
				Max:   0,
				Min:   0,
				Avg:   0,
				Unit:  "mmol/L",
				Trend: "无数据",
			},
			HealthAdvice:    []string{"暂无血糖记录，无法生成健康建议。请先进行血糖测量。"},
			DetailedRecords: detailedRecords,
			CreatedAt:       time.Now().Format("2006-01-02 15:04:05"),
		}, nil
	}

	// 4. 生成统计数据
	avgBloodSugar := totalBloodSugar / float32(recordCount)
	trend := analyzeBloodSugarTrend(detailedRecords)

	// 5. 构建完整报告
	return &BloodSugarReport{
		UserID:      userID,
		RecordCount: recordCount,
		TimeRange: TimeRange{
			Earliest: earliestTime.Format("2006-01-02 15:04:05"),
			Latest:   latestTime.Format("2006-01-02 15:04:05"),
		},
		BloodSugar: BloodSugarStats{
			Max:   maxBloodSugar,
			Min:   minBloodSugar,
			Avg:   avgBloodSugar,
			Unit:  "mmol/L",
			Trend: trend,
		},
		HealthAdvice: generateBloodSugarHealthAdvice(BloodSugarStats{
			Max:   maxBloodSugar,
			Min:   minBloodSugar,
			Avg:   avgBloodSugar,
			Unit:  "mmol/L",
			Trend: trend,
		}),
		DetailedRecords: detailedRecords,
		CreatedAt:       time.Now().Format("2006-01-02 15:04:05"),
	}, nil
}

// 解析记录ID（MongoDB的_id字段）
func parseRecordID(value interface{}) (string, error) {
	switch v := value.(type) {
	case int32:
		return strconv.FormatInt(int64(v), 10), nil
	case int64:
		return strconv.FormatInt(v, 10), nil
	case string:
		return v, nil
	default:
		return "", fmt.Errorf("不支持的_id类型: %T", v)
	}
}

// 保存血糖报告到文件
func SaveBloodSugarReportToFile(report *BloodSugarReport, dir string) (string, error) {
	if err := os.MkdirAll(dir, 0755); err != nil {
		return "", fmt.Errorf("创建目录失败: %w", err)
	}

	filename := fmt.Sprintf("blood_sugar_report_%d_%d.json", report.UserID, time.Now().Unix())
	filePath := filepath.Join(dir, filename)

	data, err := json.MarshalIndent(report, "", "  ")
	if err != nil {
		return "", fmt.Errorf("序列化失败: %w", err)
	}

	if err := os.WriteFile(filePath, data, 0644); err != nil {
		return "", fmt.Errorf("写入文件失败: %w", err)
	}
	return filePath, nil
}

// 生成并保存血糖报告
func GenerateAndSaveBloodSugarReportp(userID uint64, dir string, collectionName string) (*BloodSugarReport, string, error) {
	report, err := GenerateBloodSugarReport(userID, collectionName)
	if err != nil {
		return nil, "", fmt.Errorf("生成报告失败: %w", err)
	}

	path, err := SaveBloodSugarReportToFile(report, dir)
	if err != nil {
		return report, "", fmt.Errorf("保存报告失败: %w", err)
	}
	return report, path, nil
}
